/*
 * File JSONValue.h part of the SimpleJSON Library - http://mjpa.in/json
 *
 * Copyright (C) 2010 Mike Anchor
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef _JSONVALUE_H_
#define _JSONVALUE_H_

#include <vector>
#include <string>

#include "JSON.h"

 //#define CONVERT_UNICODE

class JSON;

enum JSONType
{
	JSONType_Null,
	JSONType_String,
	JSONType_Bool,
	JSONType_Array,
	JSONType_Object,
	JSONType_Int,
	JSONType_Double,
};

class JSONValue
{
	friend class JSON;

public:
	JSONValue(/*NULL*/);
	JSONValue(const wchar_t* m_char_value);
	JSONValue(const std::wstring& m_string_value);
	JSONValue(bool m_bool_value);
	JSONValue(double m_number_value);
	JSONValue(int m_integer_value);
	JSONValue(const JSONArray& m_array_value);
	JSONValue(const JSONObject& m_object_value);
	JSONValue(const JSONValue& m_source);
	~JSONValue();

	bool IsNull() const;
	bool IsString() const;
	bool IsBool() const;
	bool IsInt() const;
	bool IsDouble() const;
	bool IsNumber() const;
	bool IsArray() const;
	bool IsObject() const;

	const std::wstring& AsString(const std::wstring& defVal = L"") const;
	bool AsBool(bool defVal = false) const;
	double AsNumber(double defVal = 0.0) const;
	const JSONArray& AsArray() const;
	const JSONObject& AsObject() const;

	std::size_t CountChildren() const;
	bool HasChild(std::size_t index) const;
	JSONValue* Child(std::size_t index);
	bool HasChild(const wchar_t* name) const;
	JSONValue* Child(const wchar_t* name);
	std::vector<std::wstring> ObjectKeys() const;

	std::wstring Stringify(bool const prettyprint = false) const;

public:
	static JSONArray DEFAULT_ARRAY;
	static JSONObject DEFAULT_OBJECT;
	static JSONValue NULL_VALUE;

protected:
	static JSONValue* Parse(const wchar_t** data);

private:
	static std::wstring StringifyString(const std::wstring& str);
	std::wstring StringifyImpl(size_t const indentDepth) const;
	static std::wstring Indent(size_t depth);

	JSONType type;

	union
	{
		bool bool_value;
		int int_value;
		double double_value;
		std::wstring* string_value;
		JSONArray* array_value;
		JSONObject* object_value;
	};

};

#endif
